package lib.self.adapter.recycler;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import androidx.recyclerview.widget.RecyclerView.Adapter;
import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import lib.self.AppEx;
import lib.self.LogMgr;
import lib.self.adapter.interfaces.IAdapter;
import lib.self.adapter.interfaces.OnAdapterClickListener;
import lib.self.adapter.interfaces.OnRecyclerItemClickListener;
import lib.self.ex.interfaces.IFitParams;
import lib.self.ex.interfaces.IOption;
import lib.self.util.autoFit.FitDpUtil;
import lib.self.util.autoFit.FitViewParamsUtil;
import lib.self.util.view.ViewUtil;

/**
 * description: RecyclerAdapter基类 可以用于多Item
 * author: Steven Xiao
 * date: 2017/5/16
 */
public abstract class MultiRecyclerAdapterEx<T, VH extends RecyclerViewHolderEx> extends Adapter<VH> implements IFitParams, IOption, IAdapter<T> {
    protected final String TAG = getClass().getSimpleName();

    private List<T> mTs;
    private LayoutInflater mInflater = null;

    private OnRecyclerItemClickListener mItemClickListener;
    private boolean mEnableLongClick;

    private HashMap<View, ViewClickListener> mMapClickLsn = null;
    private OnAdapterClickListener mOnAdapterClickListener;

    @Override
    public VH onCreateViewHolder(ViewGroup parent, int viewType) {
        final View view = getLayoutInflater().inflate(getConvertViewResId(viewType), parent, false);
        autoFitAll(view);

        final VH vh = initViewHolder(view, viewType);

//        initView(vh.getLayoutPosition(), vh, viewType);

        view.setOnClickListener(v -> {
            if (mItemClickListener != null) {
                mItemClickListener.onItemClick(view, vh.getLayoutPosition());
            }
        });

        view.setOnLongClickListener(v -> {
            if (mEnableLongClick) {
                if (mItemClickListener != null) {
                    mItemClickListener.onItemLongClick(view, vh.getLayoutPosition());
                }
                return true;
            }
            return false;
        });

        return vh;
    }

    @Override
    public void onBindViewHolder(VH holder, int position) {
        refreshView(position, holder, getItemViewType(position));
    }

    @Override
    public int getItemCount() {
        return getCount();
    }

    /**
     * 设置点击监听
     *
     * @param listener
     */
    public final void setOnItemClickListener(OnRecyclerItemClickListener listener) {
        mItemClickListener = listener;
    }

    /**
     * 是否允许长点击
     *
     * @param enable
     */
    public final void setEnableLongClick(boolean enable) {
        this.mEnableLongClick = enable;
    }

    public LayoutInflater getLayoutInflater() {
        if (mInflater == null) {
            mInflater = LayoutInflater.from(getContext());
        }
        return mInflater;
    }

    public Context getContext() {
        return AppEx.getCt();
    }

//    protected void initView(int position, VH holder, int itemType) {
//    }

    protected abstract void refreshView(int position, VH holder, int itemType);

    public abstract int getConvertViewResId(int itemType);

    protected abstract VH initViewHolder(View view, int itemType);

    @Override
    public void setOnAdapterClickListener(OnAdapterClickListener listener) {
        mOnAdapterClickListener = listener;
    }

    @Override
    public void registerDataSetObserver(Object observer) {
        registerAdapterDataObserver((AdapterDataObserver) observer);
    }

    @Override
    public void unRegisterDataSetObserver(Object observer) {
        unregisterAdapterDataObserver((AdapterDataObserver) observer);
    }

    @Override
    public boolean isEmpty() {
        return getCount() == 0;
    }

    @Override
    public T getItem(int position) {
        if (mTs == null) {
            return null;
        }
        T t = null;
        try {
            t = mTs.get(position);
        } catch (Exception e) {
            LogMgr.e(TAG, e.toString());
        }
        return t;
    }

    @Override
    public int getLastItemPosition() {
        return 0;
    }

    @Override
    public int getCount() {
        return mTs == null ? 0 : mTs.size();
    }

    @Override
    public List<T> getData() {
        return mTs;
    }

    @Override
    public void removeAll() {
        if (mTs != null) {
            mTs.clear();
        }
    }

    @Override
    public void remove(int position) {
        if (mTs != null) {
            mTs.remove(position);
        }
    }

    @Override
    public void remove(T item) {
        if (mTs != null) {
            mTs.remove(item);
        }
    }

    @Override
    public void addAll(int position, List<T> items) {

        if (mTs != null && items != null) {
            mTs.addAll(position, items);
        }
    }

    @Override
    public void addAll(List<T> data) {
        if (data == null) {
            return;
        }
        if (mTs == null) {
            mTs = data;
        } else {
            mTs.addAll(data);
        }
    }

    @Override
    public void add(T item) {
        if (item == null) {
            return;
        }

        if (mTs == null) {
            mTs = new ArrayList<>();
        }
        mTs.add(item);
    }

    @Override
    public void add(int position, T item) {
        if (item == null) {
            return;
        }
        if (mTs == null) {
            mTs = new ArrayList<>();
        }
        mTs.add(position, item);
    }

    @Override
    public void setData(List<T> data) {
        mTs = data;
    }

    @Override
    public void autoFitAll(View view) {
        FitViewParamsUtil.autoFitAll(view);
    }

    @Override
    public int dpToPx(float dp) {
        return FitDpUtil.dpToPx(dp, getContext());
    }

    private class ViewClickListener implements OnClickListener {
        private int mPosition;

        public ViewClickListener(int position) {
            this.mPosition = position;
        }

        @Override
        public void onClick(View v) {
            onViewClick(mPosition, v);

            if (mOnAdapterClickListener != null) {
                mOnAdapterClickListener.onAdapterClick(mPosition, v);
            }
        }
    }

    /**
     * 监听控件的点击, 可以不重写, 交给外部处理
     *
     * @param position
     * @param view
     * @see #setOnAdapterClickListener(OnAdapterClickListener)
     */
    protected void onViewClick(int position, View view) {

    }

    /**
     * 根据view的id和item的position设置对应的lsn, 使用和convertView一样的缓存模式
     *
     * @param position
     * @param view
     */
    public void setOnViewClickListener(int position, View view) {
        if (view == null) {
            return;
        }

        if (mMapClickLsn == null) {
            mMapClickLsn = new HashMap<>();
        }

        ViewClickListener listener = mMapClickLsn.get(view);
        if (listener == null) {
            //表示这个view没有被设置过listener
            listener = new ViewClickListener(position);
            view.setOnClickListener(listener);
            mMapClickLsn.put(view, listener);
        } else {
            listener.mPosition = position;
        }
    }

    /**
     * 去掉点击监听, 主要是为了不响应press效果
     *
     * @param view
     */
    protected void removeOnViewClickListener(View view) {
        if (mMapClickLsn == null) {
            return;
        }

        mMapClickLsn.remove(view);
        view.setOnClickListener(null);
        view.setClickable(false);
    }

    @Override
    public void showView(View view) {
        ViewUtil.showView(view);
    }

    @Override
    public void hideView(View view) {
        ViewUtil.hideView(view);
    }

    @Override
    public void goneView(View view) {
        ViewUtil.goneView(view);
    }

    @Override
    public void startActivity(Class<? extends Activity> cls) {
        Intent intent = new Intent(getContext(), cls);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getContext().startActivity(intent);
    }

    @Override
    public void startActivityForResult(Class<? extends Activity> cls, int requestCode) {

    }
}
